﻿using LitJson;
using Newtonsoft.Json.Linq;
using PublicMethod;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Web.UI;
using WSBX.Models;

namespace OrderingOnlineWeChat.Controllers
{
    public class JsApiPayController : Controller
    {

        /////////////////此页面废弃，不做处理//////////////////////////////
        //
        // GET: /JsApiPay/
        JsApiPay jsApiPay = new JsApiPay();
        public ActionResult Index()
        {

            try
            {
                ServiceReference1.ServiceClient srconfig = new ServiceReference1.ServiceClient();
                HttpContext httpcontext = System.Web.HttpContext.Current;
                string urlCurrent = (!string.IsNullOrEmpty(httpcontext.Request.ServerVariables["HTTPS"])) && httpcontext.Request.ServerVariables["HTTPS"] != "off" ? "https://" : "http://";
                urlCurrent += System.Web.HttpContext.Current.Request.Url.Host;
                urlCurrent += httpcontext.Request.ServerVariables["URL"];
                urlCurrent += string.IsNullOrEmpty(httpcontext.Request.ServerVariables["QUERY_STRING"]) ? "" : httpcontext.Request.ServerVariables["QUERY_STRING"];
                Log.Debug("urlCurrent", urlCurrent);
                string wxResult = srconfig.Query_WxYZMsg(urlCurrent, 1); //根据url从接口获取微信配置
                string tonken = srconfig.GetAccess_token();
                JObject jb = JObject.Parse(wxResult);
                WxResult wxRes = new WxResult();

                wxRes.appId = jb["rows"]["appId"].ToString();
                wxRes.nonceStr = jb["rows"]["nonceStr"].ToString();
                wxRes.signature = jb["rows"]["signature"].ToString();
                wxRes.timestamp = jb["rows"]["timestamp"].ToString();
                ViewBag.wxRes = wxRes;

                Session["appId"] = wxRes.appId;
                Session["nonceStr"] = wxRes.nonceStr;
                Session["signature"] = wxRes.signature;
                Session["timestamp"] = wxRes.timestamp;

                Session["token"] = tonken;
                Log.Debug("token", tonken);

                
                
            }
            catch (Exception ex)
            {
                Log.Error("获取微信配置异常", ex.Message);
            }
            return View();
        }
        /// <summary>
        /// 充值
        /// </summary>
        /// <returns></returns>
        public ActionResult MeterRecharge()
        {
            object objResult = "";
            string strTotal_fee = Request.Form["totalfee"];
            string strFee = (double.Parse(strTotal_fee) * 100).ToString();

            //若传递了相关参数，则调统一下单接口，获得后续相关接口的入口参数
            Model.View_User dataresult = Session[SessionStorage.UserLogin] as Model.View_User ;//将实体类保存至Session;
            jsApiPay.openid = dataresult.AccMobile;
            Log.Debug("total_fee", strFee);
            jsApiPay.total_fee = int.Parse(strFee);

            //JSAPI支付预处理
            try
            {
                string strBody = "订单消费";//商品描述
                WxPayData unifiedOrderResult = jsApiPay.GetUnifiedOrderResult(strBody);
                WxPayData wxJsApiParam = jsApiPay.GetJsApiParameters();//获取H5调起JS API参数

                ModelForOrder aOrder = new ModelForOrder()
                {
                    appId = wxJsApiParam.GetValue("appId").ToString(),
                    nonceStr = wxJsApiParam.GetValue("nonceStr").ToString(),
                    packageValue = wxJsApiParam.GetValue("package").ToString(),
                    paySign = wxJsApiParam.GetValue("paySign").ToString(),
                    timeStamp = wxJsApiParam.GetValue("timeStamp").ToString(),
                    msg = "成功下单,正在接入微信支付."
                };
                objResult = aOrder;
            }
            catch (Exception ex)
            {
                ModelForOrder aOrder = new ModelForOrder()
                {
                    appId = "",
                    nonceStr = "",
                    packageValue = "",
                    paySign = "",
                    timeStamp = "",
                    msg = "下单失败，请重试,多次失败,请联系管理员."
                };
                objResult = aOrder;
            }
            return Json(objResult);
        }

        public class ModelForOrder
        {
            public string appId { get; set; }
            public string timeStamp { get; set; }
            public string nonceStr { get; set; }
            public string packageValue { get; set; }
            public string paySign { get; set; }

            public string msg { get; set; }
        }

        public class JsApiPay
        {
            /// <summary>
            /// 保存页面对象，因为要在类的方法中使用Page的Request对象
            /// </summary>
            private Page page { get; set; }

            /// <summary>
            /// openid用于调用统一下单接口
            /// </summary>
            public string openid { get; set; }

            /// <summary>
            /// access_token用于获取收货地址js函数入口参数
            /// </summary>
            public string access_token { get; set; }

            /// <summary>
            /// 商品金额，用于统一下单
            /// </summary>
            public int total_fee { get; set; }

            /// <summary>
            /// 统一下单接口返回结果
            /// </summary>
            public WxPayData unifiedOrderResult { get; set; }

            public JsApiPay()
            {

            }

            /**
             * 调用统一下单，获得下单结果
             * @return 统一下单结果
             * @失败时抛异常WxPayException
             */
            public WxPayData GetUnifiedOrderResult(string strBody)
            {
                //统一下单
                WxPayData data = new WxPayData();
                data.SetValue("body", strBody);
                data.SetValue("attach", "附加信息");
                data.SetValue("out_trade_no", WxPayApi.GenerateOutTradeNo()); 
                data.SetValue("total_fee", total_fee);
                data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));
                data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));
                data.SetValue("goods_tag", "test");
                data.SetValue("trade_type", "JSAPI");
                data.SetValue("openid", openid);
                WxPayData result = WxPayApi.UnifiedOrder(data);
                if (!result.IsSet("appid") || !result.IsSet("prepay_id") || result.GetValue("prepay_id").ToString() == "")
                {
                    Log.Error(this.GetType().ToString(), "UnifiedOrder response error!");
                    throw new WxPayException("UnifiedOrder response error!");
                }

                unifiedOrderResult = result;
                return result;
            }

            /**
            *  
            * 从统一下单成功返回的数据中获取微信浏览器调起jsapi支付所需的参数，
            * 微信浏览器调起JSAPI时的输入参数格式如下：
            * {
            *   "appId" : "wx2421b1c4370ec43b",     //公众号名称，由商户传入     
            *   "timeStamp":" 1395712654",         //时间戳，自1970年以来的秒数     
            *   "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串     
            *   "package" : "prepay_id=u802345jgfjsdfgsdg888",     
            *   "signType" : "MD5",         //微信签名方式:    
            *   "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 
            * }
            * @return string 微信浏览器调起JSAPI时的输入参数，json格式可以直接做参数用
            * 更详细的说明请参考网页端调起支付API：http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7
            * 
            */
            public WxPayData GetJsApiParameters()
            {

                WxPayData jsApiParam = new WxPayData();
                jsApiParam.SetValue("appId", WxPayConfig.APPID);
                jsApiParam.SetValue("timeStamp", WxPayApi.GenerateTimeStamp());
                jsApiParam.SetValue("nonceStr", WxPayApi.GenerateNonceStr());
                Log.Debug("prepay_id", unifiedOrderResult.GetValue("prepay_id").ToString());
                jsApiParam.SetValue("package", "prepay_id=" + unifiedOrderResult.GetValue("prepay_id"));
                jsApiParam.SetValue("signType", "MD5");
                jsApiParam.SetValue("paySign", jsApiParam.MakeSign());

                string parameters = jsApiParam.ToJson();
                Log.Debug(this.GetType().ToString(), "Get jsApiParam : " + parameters);
                return jsApiParam;
            } 
            //public string GetJsApiParameter()
            //{
            //    Log.Debug(this.GetType().ToString(), "JsApiPay::GetJsApiParam is processing...");

            //    WxPayData jsApiParam = new WxPayData();
            //    jsApiParam.SetValue("appId", unifiedOrderResult.GetValue("appid"));
            //    jsApiParam.SetValue("timeStamp", WxPayApi.GenerateTimeStamp());
            //    jsApiParam.SetValue("nonceStr", WxPayApi.GenerateNonceStr());
            //    jsApiParam.SetValue("package", "prepay_id=" + unifiedOrderResult.GetValue("prepay_id"));
            //    jsApiParam.SetValue("signType", "MD5");
            //    jsApiParam.SetValue("paySign", jsApiParam.MakeSign());

            //    string parameters = jsApiParam.ToJson();
            //    Log.Debug(this.GetType().ToString(), "Get jsApiParam : " + parameters);
            //    return parameters;
            //}


            /**
            * 
            * 获取收货地址js函数入口参数,详情请参考收货地址共享接口：http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_9
            * @return string 共享收货地址js函数需要的参数，json格式可以直接做参数使用
            */
            public string GetEditAddressParameters()
            {
                string parameter = "";
                try
                {
                    string host = page.Request.Url.Host;
                    string path = page.Request.Path;
                    string queryString = page.Request.Url.Query;
                    //这个地方要注意，参与签名的是网页授权获取用户信息时微信后台回传的完整url
                    string url = "http://" + host + path + queryString;

                    //构造需要用SHA1算法加密的数据
                    WxPayData signData = new WxPayData();
                    signData.SetValue("appid", WxPayConfig.APPID);
                    signData.SetValue("url", url);
                    signData.SetValue("timestamp", WxPayApi.GenerateTimeStamp());
                    signData.SetValue("noncestr", WxPayApi.GenerateNonceStr());
                    signData.SetValue("accesstoken", access_token);
                    string param = signData.ToUrl();

                    Log.Debug(this.GetType().ToString(), "SHA1 encrypt param : " + param);
                    //SHA1加密
                    string addrSign = FormsAuthentication.HashPasswordForStoringInConfigFile(param, "SHA1");
                    Log.Debug(this.GetType().ToString(), "SHA1 encrypt result : " + addrSign);

                    //获取收货地址js函数入口参数
                    WxPayData afterData = new WxPayData();
                    afterData.SetValue("appId", WxPayConfig.APPID);
                    afterData.SetValue("scope", "jsapi_address");
                    afterData.SetValue("signType", "sha1");
                    afterData.SetValue("addrSign", addrSign);
                    afterData.SetValue("timeStamp", signData.GetValue("timestamp"));
                    afterData.SetValue("nonceStr", signData.GetValue("noncestr"));

                    //转为json格式
                    parameter = afterData.ToJson();
                    Log.Debug(this.GetType().ToString(), "Get EditAddressParam : " + parameter);
                }
                catch (Exception ex)
                {
                    Log.Error(this.GetType().ToString(), ex.ToString());
                    throw new WxPayException(ex.ToString());
                }

                return parameter;
            }
        }
    }
}
